/*
 * globals.h
 *
 *  Created on: Mar 27, 2013
 *      Author: locpm
 */

#ifndef GLOBALS_H_
#define GLOBALS_H_

#include "defines.h"

char CMD_BUFF[MAX_CMD_BUFF];
unsigned int CMD_BUFF_COUNT = 0;

// Identifier of next move:
const BOOL TRUE = 1;
const BOOL FALSE = 0;

// Identifier of next move:
const unsigned char WHITE_MOVE = 0;
const unsigned char BLACK_MOVE = 1;

BOARD board;

/*
	RANKS:
	   9 |       81   82   83   84   85   86   87   88    89    (MSB,
	   8 |       72   73   74   75   76   77   78   79    80    left)
	   7 |       63   64   65   66   67   68   69   70    71
	   6 |       54   55   56   57   58   59   60   51    62
	   5 |       45   46   47   48   49   50   51   52    53
	   4 |       36   37   38   39   40   41   42   43    44
	   3 |       27   28   29   30   31   32   33   34    35
	   2 |       18   19   20   21   22   23   24   25    26
	   1 |        9   10   11   12   13   14   15   16    17
	   0 | (LSB,  0    1    2    3    4    5    6    7    8
		 |  right)
		  ----------------------------------------------------
	 FILES:       a    b    c    d    e    f    g    h    i
*/

const unsigned int A0 = 0;
const unsigned int A1 = 9;
const unsigned int A2 = 18;
const unsigned int A3 = 27;
const unsigned int A4 = 36;
const unsigned int A5 = 45;
const unsigned int A6 = 54;
const unsigned int A7 = 63;
const unsigned int A8 = 72;
const unsigned int A9 = 81;

const unsigned int B0 = 1;
const unsigned int B1 = 10;
const unsigned int B2 = 19;
const unsigned int B3 = 28;
const unsigned int B4 = 37;
const unsigned int B5 = 46;
const unsigned int B6 = 55;
const unsigned int B7 = 64;
const unsigned int B8 = 73;
const unsigned int B9 = 82;

const unsigned int C0 = 2;
const unsigned int C1 = 11;
const unsigned int C2 = 20;
const unsigned int C3 = 29;
const unsigned int C4 = 38;
const unsigned int C5 = 47;
const unsigned int C6 = 56;
const unsigned int C7 = 65;
const unsigned int C8 = 74;
const unsigned int C9 = 83;

const unsigned int D0 = 3;
const unsigned int D1 = 12;
const unsigned int D2 = 21;
const unsigned int D3 = 30;
const unsigned int D4 = 39;
const unsigned int D5 = 48;
const unsigned int D6 = 57;
const unsigned int D7 = 66;
const unsigned int D8 = 75;
const unsigned int D9 = 84;

const unsigned int E0 = 4;
const unsigned int E1 = 13;
const unsigned int E2 = 22;
const unsigned int E3 = 31;
const unsigned int E4 = 40;
const unsigned int E5 = 49;
const unsigned int E6 = 58;
const unsigned int E7 = 67;
const unsigned int E8 = 76;
const unsigned int E9 = 85;

const unsigned int F0 = 5;
const unsigned int F1 = 14;
const unsigned int F2 = 23;
const unsigned int F3 = 32;
const unsigned int F4 = 41;
const unsigned int F5 = 50;
const unsigned int F6 = 59;
const unsigned int F7 = 68;
const unsigned int F8 = 77;
const unsigned int F9 = 86;

const unsigned int G0 = 6;
const unsigned int G1 = 15;
const unsigned int G2 = 24;
const unsigned int G3 = 33;
const unsigned int G4 = 42;
const unsigned int G5 = 51;
const unsigned int G6 = 60;
const unsigned int G7 = 69;
const unsigned int G8 = 78;
const unsigned int G9 = 87;

const unsigned int H0 = 7;
const unsigned int H1 = 16;
const unsigned int H2 = 25;
const unsigned int H3 = 34;
const unsigned int H4 = 43;
const unsigned int H5 = 52;
const unsigned int H6 = 61;
const unsigned int H7 = 70;
const unsigned int H8 = 79;
const unsigned int H9 = 88;

const unsigned int I0 = 8;
const unsigned int I1 = 17;
const unsigned int I2 = 26;
const unsigned int I3 = 35;
const unsigned int I4 = 44;
const unsigned int I5 = 53;
const unsigned int I6 = 62;
const unsigned int I7 = 71;
const unsigned int I8 = 80;
const unsigned int I9 = 89;

const char* SQUARENAME[90] = {"a0","b0","c0","d0","e0","f0","g0","h0", "i0",
                              "a1","b1","c1","d1","e1","f1","g1","h1", "i1",
                              "a2","b2","c2","d2","e2","f2","g2","h2", "i2",
                              "a3","b3","c3","d3","e3","f3","g3","h3", "i3",
                              "a4","b4","c4","d4","e4","f4","g4","h4", "i4",
                              "a5","b5","c5","d5","e5","f5","g5","h5", "i5",
                              "a6","b6","c6","d6","e6","f6","g6","h6", "i6",
                              "a7","b7","c7","d7","e7","f7","g7","h7", "i7",
                              "a8","b8","c8","d8","e8","f8","g8","h8", "i8",
                              "a9","b9","c9","d9","e9","f9","g9","h9", "i9"};

// white = 0xxx, black = 1xxx
const unsigned char EMPTY = 0;                //  0000
const unsigned char WHITE_PAWN = 1;           //  0001
const unsigned char WHITE_KING = 2;           //  0010
const unsigned char WHITE_ADVISOR = 3;        //  0011
const unsigned char WHITE_ELEPHANT =  4;      //  0100
const unsigned char WHITE_ROOK = 5;           //  0101
const unsigned char WHITE_CANNON = 6;         //  0110
const unsigned char WHITE_HORSE = 7;          //  0111
const unsigned char BLACK_PAWN = 8;           //  1000
const unsigned char BLACK_KING = 9;           //  1001
const unsigned char BLACK_ADVISOR = 10;       //  1010
const unsigned char BLACK_ELEPHANT = 11;      //  1011
const unsigned char BLACK_ROOK = 12;          //  1100
const unsigned char BLACK_CANNON = 13;        //  1101
const unsigned char BLACK_HORSE = 14;         //  1110

const char PIECENAMES[15] = {'.','P','K','A','E','R','C','H',
                             'p','k','a','e','r','c','h'};

// BITSET has only one bit set
U32 BITSET[30];

// BITBOARDSET has only one bit set
BITBOARD BITBOARDSET[90];

// BOARDINDEX is used to translate [file][rank] to [square]
unsigned int BOARDINDEX[9][10];

BOOL debugMode;

// Square to bitboard index
const unsigned int SQUARE_TO_BITBOARD_INDEX[90] = {
		0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 2, 2, 2,
		2, 2, 2, 2, 2, 2, 2, 2, 2,
		2, 2, 2, 2, 2, 2, 2, 2, 2,
		2, 2, 2, 2, 2, 2, 2, 2, 2
};

// Square to bitset index
const unsigned int SQUARE_TO_BITSET_INDEX[90] = {
		 0,  1,  2,  3,  4,  5,  6,  7,  8,
		 9, 10, 11, 12, 13, 14, 15, 16, 17,
		18, 19, 20, 21, 22, 23, 24, 25, 26,
		27, 28, 29,  0,  1,  2,  3,  4,  5,
		 6,  7,  8,  9, 10, 11, 12, 13, 14,
		15, 16, 17, 18, 19, 20, 21, 22, 23,
		24, 25, 26, 27, 28, 29,  0,  1,  2,
		 3,  4,  5,  6,  7,  8,  9, 10, 11,
		12, 13, 14, 15, 16, 17, 18, 19, 20,
		21, 22, 23, 24, 25, 26, 27, 28, 29,
};

// FILES is used to translate [square] [file]
const unsigned int FILES[90] = {
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8,
		0, 1, 2, 3, 4, 5, 6, 7, 8
};

// RANKS is used to translate [square] [rank]
const unsigned int RANKS[90] = {
		0, 0, 0, 0, 0, 0, 0, 0, 0,
		1, 1, 1, 1, 1, 1, 1, 1, 1,
		2, 2, 2, 2, 2, 2, 2, 2, 2,
		3, 3, 3, 3, 3, 3, 3, 3, 3,
		4, 4, 4, 4, 4, 4, 4, 4, 4,
		5, 5, 5, 5, 5, 5, 5, 5, 5,
		6, 6, 6, 6, 6, 6, 6, 6, 6,
		7, 7, 7, 7, 7, 7, 7, 7, 7,
		8, 8, 8, 8, 8, 8, 8, 8, 8,
		9, 9, 9, 9, 9, 9, 9, 9, 9
};

const unsigned int INDEX32[32] = {
			 0,  1, 28,  2, 29, 14, 24, 3,
			30, 22, 20, 15, 25, 17,  4, 8,
			31, 27, 13, 23, 21, 19, 16, 7,
			26, 12, 18,  6, 11,  5, 10, 9
	};

const unsigned int DEBRUIJN32 = 0x077CB531;

// Attack tables:
BITBOARD HORSE_ATTACKS[90][4];
BITBOARD HORSE_OBSTRUCTS[90][4];
BITBOARD ELEPHANT_ATTACKS[90][4];
BITBOARD ELEPHANT_OBSTRUCTS[90][4];
BITBOARD ADVISOR_ATTACKS[90];
BITBOARD KING_ATTACKS[90];
BITBOARD WHITE_PAWN_ATTACKS[90];
BITBOARD BLACK_PAWN_ATTACKS[90];

BITBOARD ATTACKS_RIGHT[90];
BITBOARD ATTACKS_TOP[90];
BITBOARD ATTACKS_LEFT[90];
BITBOARD ATTACKS_BOTTOM[90];

const int PAWN_VALUE = 66;
const int KING_VALUE = 6000;
const int ADVISOR_VALUE = 133;
const int ELEPHANT_VALUE = 166;
const int ROOK_VALUE = 600;
const int CANNON_VALUE = 300;
const int HORSE_VALUE = 266;

// Search parameters start here:
const int LARGE_NUMBER = 6000 + 1; // KING_VALUE + 1
const int CHECKMATESCORE = 6000; // KING_VALUE
MOVE NOMOVE;

// Default search depth
const int DEFAULT_SEARCH_DEPTH = 4;

// This constant is used in notBitBoard(BITBOARD) function
// In binary: 0011 1111 1111 1111 1111 1111 1111 1111
// The first two bits are not used in BITBOARD struct
const U32 LAST_THIRTY_BIT_SET = 0x3FFFFFFF;

#endif /* GLOBALS_H_ */
